home *** CD-ROM | disk | FTP | other *** search
- /*
- * hfsutils - tools for reading and writing Macintosh HFS volumes
- * Copyright (C) 1996, 1997 Robert Leslie
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- # include <time.h>
- # include <standard.h>
-
- # include "hfs.h"
-
- # define ERROR(code, str) (hfs_error = (str), errno = (code))
-
- # define SIZE(type, n) ((size_t) (sizeof(type) * (n)))
- # define ALLOC(type, n) ((type *) malloc(SIZE(type, n)))
- # define ALLOCX(type, n) ((n) ? ALLOC(type, n) : (type *) 0)
- # define FREE(ptr) {if (ptr) free((void *) ptr) ;}
-
- # define REALLOC(ptr, type, n) \
- ((type *) ((ptr) ? realloc(ptr, SIZE(type, n)) : malloc(SIZE(type, n))))
- # define REALLOCX(ptr, type, n) \
- ((n) ? REALLOC(type, n) : (FREE(ptr), (type *) 0))
-
- # define BMTST(bm, num) \
- (((char *) (bm))[(num) >> 3] & (0x80 >> ((num) & 0x07)))
- # define BMSET(bm, num) \
- (((char *) (bm))[(num) >> 3] |= (0x80 >> ((num) & 0x07)))
- # define BMCLR(bm, num) \
- (((char *) (bm))[(num) >> 3] &= ~(0x80 >> ((num) & 0x07)))
-
- typedef unsigned char block[HFS_BLOCKSZ];
-
- typedef signed char Char;
- typedef unsigned char UChar;
- typedef signed char SignedByte;
- typedef signed short Integer;
- typedef unsigned short UInteger;
- typedef signed long LongInt;
- typedef unsigned long ULongInt;
- typedef char Str15[16];
- typedef char Str31[32];
- typedef long OSType;
-
- typedef struct {
- UInteger xdrStABN; /* first allocation block */
- UInteger xdrNumABlks; /* number of allocation blocks */
- } ExtDescriptor;
-
- typedef ExtDescriptor ExtDataRec[3];
-
- typedef struct {
- SignedByte xkrKeyLen; /* key length */
- SignedByte xkrFkType; /* fork type (0x00/0xff == data/resource */
- ULongInt xkrFNum; /* file number */
- UInteger xkrFABN; /* starting file allocation block */
- } ExtKeyRec;
-
- typedef struct {
- SignedByte ckrKeyLen; /* key length */
- SignedByte ckrResrv1; /* reserved */
- ULongInt ckrParID; /* parent directory ID */
- Str31 ckrCName; /* catalog node name */
- } CatKeyRec;
-
- # define HFS_MAP1SZ 256
- # define HFS_MAPXSZ 492
-
- # define HFS_NODEREC(nd, rnum) ((nd).data + (nd).roff[rnum])
-
- # define HFS_RECKEYLEN(ptr) (*(unsigned char *) (ptr))
- # define HFS_RECKEYSKIP(ptr) ((1 + HFS_RECKEYLEN(ptr) + 1) & ~1)
- # define HFS_RECDATA(ptr) ((ptr) + HFS_RECKEYSKIP(ptr))
-
- # define HFS_CATDATALEN sizeof(CatDataRec)
- # define HFS_EXTDATALEN sizeof(ExtDataRec)
-
- # define HFS_CATKEYLEN sizeof(CatKeyRec)
- # define HFS_EXTKEYLEN sizeof(ExtKeyRec)
-
- # define HFS_CATRECMAXLEN (HFS_CATKEYLEN + HFS_CATDATALEN)
- # define HFS_EXTRECMAXLEN (HFS_EXTKEYLEN + HFS_EXTDATALEN)
-
- # define HFS_MAXRECLEN HFS_CATRECMAXLEN
-
- typedef struct {
- Integer v; /* vertical coordinate */
- Integer h; /* horizontal coordinate */
- } Point;
-
- typedef struct {
- Integer top; /* top edge of rectangle */
- Integer left; /* left edge */
- Integer bottom; /* bottom edge */
- Integer right; /* rightmost edge */
- } Rect;
-
- typedef struct {
- Rect frRect; /* folder's rectangle */
- Integer frFlags; /* flags */
- Point frLocation; /* folder's location */
- Integer frView; /* folder's view */
- } DInfo;
-
- typedef struct {
- Point frScroll; /* scroll position */
- LongInt frOpenChain; /* directory ID chain of open folders */
- Integer frUnused; /* reserved */
- Integer frComment; /* comment ID */
- LongInt frPutAway; /* directory ID */
- } DXInfo;
-
- typedef struct {
- OSType fdType; /* file type */
- OSType fdCreator; /* file's creator */
- Integer fdFlags; /* flags */
- Point fdLocation; /* file's location */
- Integer fdFldr; /* file's window */
- } FInfo;
-
- typedef struct {
- Integer fdIconID; /* icon ID */
- Integer fdUnused[4]; /* reserved */
- Integer fdComment; /* comment ID */
- LongInt fdPutAway; /* home directory ID */
- } FXInfo;
-
- typedef struct {
- Integer drSigWord; /* volume signature (0x4244 for HFS) */
- LongInt drCrDate; /* date and time of volume creation */
- LongInt drLsMod; /* date and time of last modification */
- Integer drAtrb; /* volume attributes */
- UInteger drNmFls; /* number of files in root directory */
- UInteger drVBMSt; /* first block of volume bit map (always 3) */
- UInteger drAllocPtr; /* start of next allocation search */
- UInteger drNmAlBlks; /* number of allocation blocks in volume */
- ULongInt drAlBlkSiz; /* size (in bytes) of allocation blocks */
- ULongInt drClpSiz; /* default clump size */
- UInteger drAlBlSt; /* first allocation block in volume */
- LongInt drNxtCNID; /* next unused catalog node ID (dir/file ID) */
- UInteger drFreeBks; /* number of unused allocation blocks */
- char drVN[28]; /* volume name (1-27 chars) */
- LongInt drVolBkUp; /* date and time of last backup */
- Integer drVSeqNum; /* volume backup sequence number */
- ULongInt drWrCnt; /* volume write count */
- ULongInt drXTClpSiz; /* clump size for extents overflow file */
- ULongInt drCTClpSiz; /* clump size for catalog file */
- UInteger drNmRtDirs; /* number of directories in root directory */
- ULongInt drFilCnt; /* number of files in volume */
- ULongInt drDirCnt; /* number of directories in volume */
- LongInt drFndrInfo[8]; /* information used by the Finder */
- UInteger drVCSize; /* size (in blocks) of volume cache */
- UInteger drVBMCSize; /* size (in blocks) of volume bitmap cache */
- UInteger drCtlCSize; /* size (in blocks) of common volume cache */
- ULongInt drXTFlSize; /* size (in bytes) of extents overflow file */
- ExtDataRec drXTExtRec; /* first extent record for extents file */
- ULongInt drCTFlSize; /* size (in bytes) of catalog file */
- ExtDataRec drCTExtRec; /* first extent record for catalog file */
- } MDB;
-
- # define HFS_ATRB_BUSY (1 << 6)
- # define HFS_ATRB_HLOCKED (1 << 7)
- # define HFS_ATRB_UMOUNTED (1 << 8)
- # define HFS_ATRB_BBSPARED (1 << 9)
- # define HFS_ATRB_COPYPROT (1 << 14)
- # define HFS_ATRB_SLOCKED (1 << 15)
-
- typedef enum {
- cdrDirRec = 1,
- cdrFilRec = 2,
- cdrThdRec = 3,
- cdrFThdRec = 4
- } CatDataType;
-
- typedef struct {
- SignedByte cdrType; /* record type */
- SignedByte cdrResrv2; /* reserved */
- union {
- struct { /* cdrDirRec */
- Integer dirFlags; /* directory flags */
- UInteger dirVal; /* directory valence */
- ULongInt dirDirID; /* directory ID */
- LongInt dirCrDat; /* date and time of creation */
- LongInt dirMdDat; /* date and time of last modification */
- LongInt dirBkDat; /* date and time of last backup */
- DInfo dirUsrInfo; /* Finder information */
- DXInfo dirFndrInfo; /* additional Finder information */
- LongInt dirResrv[4]; /* reserved */
- } dir;
- struct { /* cdrFilRec */
- SignedByte
- filFlags; /* file flags */
- SignedByte
- filTyp; /* file type */
- FInfo filUsrWds; /* Finder information */
- ULongInt filFlNum; /* file ID */
- UInteger filStBlk; /* first alloc block of data fork */
- ULongInt filLgLen; /* logical EOF of data fork */
- ULongInt filPyLen; /* physical EOF of data fork */
- UInteger filRStBlk; /* first alloc block of resource fork */
- ULongInt filRLgLen; /* logical EOF of resource fork */
- ULongInt filRPyLen; /* physical EOF of resource fork */
- LongInt filCrDat; /* date and time of creation */
- LongInt filMdDat; /* date and time of last modification */
- LongInt filBkDat; /* date and time of last backup */
- FXInfo filFndrInfo; /* additional Finder information */
- UInteger filClpSize; /* file clump size */
- ExtDataRec
- filExtRec; /* first data fork extent record */
- ExtDataRec
- filRExtRec; /* first resource fork extent record */
- LongInt filResrv; /* reserved */
- } fil;
- struct { /* cdrThdRec */
- LongInt thdResrv[2]; /* reserved */
- ULongInt thdParID; /* parent ID for this directory */
- Str31 thdCName; /* name of this directory */
- } dthd;
- struct { /* cdrFThdRec */
- LongInt fthdResrv[2]; /* reserved */
- ULongInt fthdParID; /* parent ID for this file */
- Str31 fthdCName; /* name of this file */
- } fthd;
- } u;
- } CatDataRec;
-
- struct _hfsfile_ {
- struct _hfsvol_ *vol; /* pointer to volume descriptor */
- long parid; /* parent directory ID of this file */
- char name[HFS_MAX_FLEN + 1]; /* catalog name of this file */
- CatDataRec cat; /* catalog information */
- ExtDataRec ext; /* current extent record */
- unsigned int fabn; /* starting file allocation block number */
- int fork; /* current selected fork for I/O */
- unsigned long pos; /* current file seek pointer */
- unsigned long clump; /* file's clump size, for allocation */
- int flags; /* bit flags */
-
- struct _hfsfile_ *prev;
- struct _hfsfile_ *next;
- };
-
- # define HFS_UPDATE_CATREC 0x01
-
- typedef struct {
- ULongInt ndFLink; /* forward link */
- ULongInt ndBLink; /* backward link */
- SignedByte ndType; /* node type */
- SignedByte ndNHeight; /* node level */
- UInteger ndNRecs; /* number of records in node */
- Integer ndResv2; /* reserved */
- } NodeDescriptor;
-
- # define HFS_MAXRECS 35 /* maximum based on minimum record size */
-
- typedef struct _node_ {
- struct _btree_ *bt; /* btree to which this node belongs */
- unsigned long nnum; /* node index */
- NodeDescriptor nd; /* node descriptor */
- int rnum; /* current record index */
- UInteger roff[HFS_MAXRECS + 1]; /* record offsets */
- block data; /* raw contents of node */
- } node;
-
- enum {
- ndIndxNode = 0x00,
- ndHdrNode = 0x01,
- ndMapNode = 0x02,
- ndLeafNode = 0xff
- };
-
- struct _hfsdir_ {
- struct _hfsvol_ *vol; /* associated volume */
- long dirid; /* directory ID of interest (or 0) */
-
- node n; /* current B*-tree node */
- struct _hfsvol_ *vptr; /* current volume pointer */
-
- struct _hfsdir_ *prev;
- struct _hfsdir_ *next;
- };
-
- typedef struct {
- UInteger bthDepth; /* current depth of tree */
- ULongInt bthRoot; /* number of root node */
- ULongInt bthNRecs; /* number of leaf records in tree */
- ULongInt bthFNode; /* number of first leaf node */
- ULongInt bthLNode; /* number of last leaf node */
- UInteger bthNodeSize; /* size of a node */
- UInteger bthKeyLen; /* maximum length of a key */
- ULongInt bthNNodes; /* total number of nodes in tree */
- ULongInt bthFree; /* number of free nodes */
- SignedByte bthResv[76]; /* reserved */
- } BTHdrRec;
-
- typedef struct _btree_ {
- hfsfile f; /* subset file information */
- node hdrnd; /* header node */
- BTHdrRec hdr; /* header record */
- char *map; /* usage bitmap */
- unsigned long mapsz; /* number of bytes in bitmap */
- int flags; /* bit flags */
-
- int (*compare) __PR((unsigned char *, unsigned char *));
- /* key comparison function */
- } btree;
-
- # define HFS_UPDATE_BTHDR 0x01
-
- struct _hfsvol_ {
- int fd; /* volume's open file descriptor */
- int flags; /* bit flags */
-
- #ifdef APPLE_HYB
- hce_mem *hce; /* Extras needed by libhfs/mkisofs */
- #endif /* APPLE_HYB */
-
- int pnum; /* ordinal HFS partition number */
- unsigned long vstart; /* logical block offset to start of volume */
- unsigned long vlen; /* number of logical blocks in volume */
- unsigned int lpa; /* number of logical blocks per allocation block */
-
- MDB mdb; /* master directory block */
- block *vbm; /* volume bit map */
- btree ext; /* B*-tree control block for extents overflow file */
- btree cat; /* B*-tree control block for catalog file */
- long cwd; /* directory id of current working directory */
-
- int refs; /* number of external references to this volume */
- hfsfile *files; /* list of open files */
- hfsdir *dirs; /* list of open directories */
-
- struct _hfsvol_ *prev;
- struct _hfsvol_ *next;
- };
-
- # define HFS_READONLY 0x01
-
- # define HFS_UPDATE_MDB 0x10
- # define HFS_UPDATE_ALTMDB 0x20
- # define HFS_UPDATE_VBM 0x40
-
- extern hfsvol *hfs_mounts;
- extern hfsvol *hfs_curvol;
-